unit USFPackageForm;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, ComCtrls, ToolWin, ImgList, ExtDlgs, XPMan,
  uPackage, uUSFExtendedPackage;

type
  TfmUSFPackage = class(TForm)
    ListView1: TListView;
    OpenDialog1: TOpenDialog;
    ToolBar1: TToolBar;
    StatusBar1: TStatusBar;
    ToolButton1: TToolButton;
    ToolButton2: TToolButton;
    tbExport: TToolButton;
    ImageList1: TImageList;
    ToolButton3: TToolButton;
    tbRepack: TToolButton;
    tbDelEntry: TToolButton;
    OpenTex: TOpenPictureDialog;
    ToolButton6: TToolButton;
    tbAddVar: TToolButton;
    tbAddTex: TToolButton;
    tbAddFile: TToolButton;
    tbRename: TToolButton;
    SaveDialog1: TSaveDialog;
    ToolButton7: TToolButton;
    ImageList2: TImageList;
    procedure Button1Click(Sender: TObject);
    procedure FormClose(Sender: TObject; var Action: TCloseAction);
    procedure Button3Click(Sender: TObject);
    procedure ListView1SelectItem(Sender: TObject; Item: TListItem;
      Selected: Boolean);
    procedure Button4Click(Sender: TObject);
    procedure tbDelEntryClick(Sender: TObject);
    procedure tbAddTexClick(Sender: TObject);
    procedure tbRenameClick(Sender: TObject);
    procedure tbAddVarClick(Sender: TObject);
    procedure ToolButton7Click(Sender: TObject);
    procedure ListView1Edited(Sender: TObject; Item: TListItem;
      var S: String);
    procedure ListView1DblClick(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    OpenedPk: TUSFExtendedPackage;
    procedure MakeTest;
    procedure OpenPackage(fn: string);
    procedure OpenPk(pk: TUSFExtendedPackage);
    procedure RefreshList;
  end;

var
  fmUSFPackage: TfmUSFPackage;

implementation

{$R *.dfm}

uses DDS,TGA, USFAddVarForm, LegacyStream, StrUtils,
  uPackageUtils, uPackageCollection, USFTextureView;

function AppDir(): string;
begin
  Result := IncludeTrailingpathDelimiter(ExtractFilepath(Application.ExeName));
end;

{ TfmUSFPackage }

procedure TfmUSFPackage.MakeTest;
begin
  uPackage.MakeTestPackage(AppDir+'test.usc');
end;

procedure TfmUSFPackage.Button1Click(Sender: TObject);
begin
  if OpenDialog1.Execute then OpenPackage(OpenDialog1.FileName);
end;

procedure TfmUSFPackage.openPackage(fn: string);
begin
  Caption := 'USF Package Editor';
  if Assigned(OpenedPk) then OpenedPk.Free;

  try
    OpenedPk := TUSFExtendedPackage.Create(fn);
    Caption := 'USF Package Editor - ['+OpenedPk.PackageName+']';
    RefreshList;
    tbRepack.Enabled := true;
    tbAddFile.Enabled := true;
    tbAddVar.Enabled := true;
    tbAddTex.Enabled := true;
    tbRename.Enabled := true;
  except
    On e:Exception do ShowMessage(E.Message);
  end;
end;

procedure TfmUSFPackage.FormClose(Sender: TObject;
  var Action: TCloseAction);
begin
  //if Assigned(OpenedPk) then OpenedPk.Free;
  Action := caFree;
end;

procedure TfmUSFPackage.RefreshList;
var i: integer;
begin
  ListView1.Clear;
  for i := 0 to OpenedPk.Count-1 do
    with ListView1.Items.Add do begin
      Caption := OpenedPk.EntryByIndex[i].Name;
      SubItems.Add(OpenedPk.EntryByIndex[i].DataClassString);
      SubItems.Add(IntToStr(OpenedPk.EntryByIndex[i].DataSize));

      case OpenedPk.EntryByIndex[i].DataClass of
        ucExtended: ImageIndex := -1;
        ucTexture: ImageIndex := 2;
        ucMesh,ucBinary: ImageIndex := 1;
        else ImageIndex := 0;
      end;
      if OpenedPk.EntryByIndex[i].Compressed then
        StateIndex := 3 else StateIndex := -1;

      case OpenedPk.EntryByIndex[i].DataClass of
        ucTexture: SubItems.Add(Format('<%s, %dx%d>', [
          TUSFTextureEntry(OpenedPk.EntryByIndex[i]).TextureFormatStr,
          TUSFTextureEntry(OpenedPk.EntryByIndex[i]).Width,
          TUSFTextureEntry(OpenedPk.EntryByIndex[i]).Height]
        ));
        ucMesh: SubItems.Add('<Mesh>');
        ucBinary: SubItems.Add('<Binary>');
        else
          SubItems.Add(TUSFVariableEntry(OpenedPk.EntryByIndex[i]).AsString);
      end;
      Data := OpenedPk.EntryByIndex[i];
    end;
end;

procedure TfmUSFPackage.Button3Click(Sender: TObject);
begin
  OpenedPk.Repack;
  self.RefreshList;
end;

procedure TfmUSFPackage.ListView1SelectItem(Sender: TObject;
  Item: TListItem; Selected: Boolean);
begin
  tbDelEntry.Enabled := selected;
  if Selected then
    tbExport.Enabled := TUSFPackageEntry(Item.Data).DataClass in [ucBinary,ucTexture,ucMesh];
end;

procedure TfmUSFPackage.Button4Click(Sender: TObject);
var fs: TFileStream;
begin
  fs := TFileStream.Create('test.uout',fmCreate);
  try
    TUSFPackageEntry(ListView1.Selected.Data).CopyToStream(fs);
  finally fs.Free; end;
end;

procedure TfmUSFPackage.tbDelEntryClick(Sender: TObject);
begin
  if Application.MessageBox('Delete entry?','Delete',MB_ICONQUESTION or MB_YESNO) = IDYES then
    if OpenedPk.DeleteEntry(ListView1.Selected.Caption) then
      RefreshList;
end;

procedure TfmUSFPackage.tbAddTexClick(Sender: TObject);
var s: string;
begin
  if OpenTex.Execute then begin
    s := ExtractFileName(OpenTex.FileName);
    if InputQuery('Add texture','Enter texture ID:', s) then
      if not OpenedPk.AddTexture(s, OpenTex.FileName) then
        ShowMessage('Failed to add texture')
      else self.RefreshList;
  end;
end;

procedure TfmUSFPackage.tbRenameClick(Sender: TObject);
var s: string;
begin
  s := OpenedPk.PackageName;
  if InputQuery('Rename package','Enter package name (32 chars max):',s) then
    OpenedPk.PackageName := s;
  Caption := 'USF Package Editor - ['+OpenedPk.PackageName+']';
end;

procedure TfmUSFPackage.tbAddVarClick(Sender: TObject);
begin
  with TfmAddVar.Create(nil) do begin
    if ShowModal = mrOK then
      if not OpenedPk.IsSet(edName.Text) then begin
        case TUSFDataClass(cbClass.ItemIndex) of
          ucByte: OpenedPk.Add(edName.Text, byte(StrToInt(edValue.Text)));
          ucWord: OpenedPk.Add(edName.Text, word(StrToInt(edValue.Text)));
          ucInteger: OpenedPk.Add(edName.Text, StrToInt(edValue.Text));
          ucCardinal: OpenedPk.Add(edName.Text, cardinal(StrToInt(edValue.Text)));
          ucFloat: OpenedPk.Add(edName.Text, StrToFloat(AnsiReplaceText(edValue.Text,'.',DecimalSeparator)));
          ucInt64: OpenedPk.Add(edName.Text, int64(StrToInt(edValue.Text)));
          //ucIdentifier,
          //ucString,
          //ucWideString: OpenedPk.Add(edName.Text, edValue.Text);
        end;
      end else
        ShowMessage('Entry with this name already exists!');
    Free;
  end;
end;

procedure TfmUSFPackage.ToolButton7Click(Sender: TObject);
begin
  if SaveDialog1.Execute then begin
    if Assigned(OpenedPk) then OpenedPk.Free;
    OpenedPk := TUSFExtendedPackage.Create(SaveDialog1.FileName, fmCreate);
    self.OpenPackage(SaveDialog1.FileName);
  end;
end;

procedure TfmUSFPackage.ListView1Edited(Sender: TObject; Item: TListItem;
  var S: String);
begin
  if S = '' then begin
    S := Item.Caption;
    exit;
  end;
  TUSFPackageEntry(Item.Data).Name := s;
end;

procedure TfmUSFPackage.OpenPk(pk: TUSFExtendedPackage);
begin
  Caption := 'USF Package Editor';
  //if Assigned(OpenedPk) then OpenedPk.Free;

  try
    OpenedPk := pk;
    Caption := 'USF Package Editor - ['+OpenedPk.PackageName+']';
    RefreshList;
    tbRepack.Enabled := true;
    tbAddFile.Enabled := true;
    tbAddVar.Enabled := true;
    tbAddTex.Enabled := true;
    tbRename.Enabled := true;
  except
    On e:Exception do ShowMessage(E.Message);
  end;
end;

procedure TfmUSFPackage.ListView1DblClick(Sender: TObject);
begin
  if not Assigned(ListView1.Selected) then exit;
  if not (TUSFPackageEntry(ListView1.Selected.Data) is TUSFTextureEntry) then exit;

  fm3DView.Show;
  fm3DView.GLCube1.Material.Texture.Disabled := false;
  if LoadTexImageFromUSFEntry(
    TUSFTextureEntry(ListView1.Selected.Data),
    fm3DView.GLML.TextureByName('Preview'),
    pmAlways
  ) then fm3DView.Caption := 'Texture view: '+OpenedPk.PackageName+'.'+TUSFPackageEntry(ListView1.Selected.Data).Name;
end;

end.
